/**
 * CrossDelay
 * <p/>
 * User: joakimd
 * Date: 2013-03-11
 * Time: 17:05
 */
package org.dru.masic.effects.crossdelay {
import org.dru.masic.MasicComponent;
import org.dru.masic.MasicInput;
import org.dru.masic.MasicOutput;
import org.dru.masic.MasicParameter;
import org.dru.stk.StkDelay;

public final class CrossDelay extends MasicComponent {
    private var _in: MasicInput;
    private var _out: MasicOutput;
    private var _durL: MasicParameter;
    private var _durR: MasicParameter;
    private var _feedback: MasicParameter;
    private var _dry: MasicParameter;
    private var _wet: MasicParameter;

    private var _dlyL: StkDelay;
    private var _dlyR: StkDelay;

    public function CrossDelay() {
        _in = createInput("in", true);
        _out = createOutput("out", true);
        _durL = createParameter("dur. L", 0, 60.0 * 44100.0 / 125.0 * 2.0 / 4.0, encode, decode);
        _durR = createParameter("dur. R", 0, 60.0 * 44100.0 / 125.0 * 3.0 / 4.0, encode, decode);
        _feedback = createParameter("feedback", 0, 0.75, encode, decode);
        _dry = createParameter("dry", 0, 0.75, encode, decode);
        _wet = createParameter("wet", 0, 0.25, encode, decode);
        _dlyL = new StkDelay(88200);
        _dlyR = new StkDelay(88200);
        //
        _dlyL.setDuration(_durL.value);
        _dlyR.setDuration(_durR.value);
    }

    override public function processSamples(start: int, end: int): void {
        const srcL: Vector.<Number> = _in.left;
        const srcR: Vector.<Number> = _in.right;
        const dstL: Vector.<Number> = _out.left;
        const dstR: Vector.<Number> = _out.right;
        const dlyL: StkDelay = this._dlyL;
        const dlyR: StkDelay = this._dlyR;
        const feedback: Number = _feedback.value;
        const dry: Number = _dry.value;
        const wet: Number = _wet.value;
        for (var pos: int = start; pos < end; pos++) {
            const inL: Number = srcL[pos];
            const inR: Number = srcR[pos];
            const tmpL: Number = dlyL.next(dlyR.current() * feedback + inL);
            const tmpR: Number = dlyR.next(dlyL.current() * feedback + inR);
            dstL[pos] = inL * dry + tmpL * wet;
            dstR[pos] = inR * dry + tmpR * wet;
        }
    }

    private static function encode(value: Number): String {
        return String(value);
    }

    private static function decode(value: String): Number {
        return Number(value);
    }
}
}
